package com.yeskery.nut.core;

import com.yeskery.nut.application.ApplicationType;
import com.yeskery.nut.application.NutApplication;
import com.yeskery.nut.application.NutConfigureImpl;
import com.yeskery.nut.bind.validator.HibernateMethodParamValidatorAutoDetectorProvider;
import com.yeskery.nut.extend.responsive.JsonResponsivePluginAutoDetectorProvider;
import com.yeskery.nut.extend.responsive.XmlResponsivePluginAutoDetectorProvider;
import com.yeskery.nut.view.ViewResolverAutoDetectorProvider;

import java.util.Set;

/**
 * 默认的自动检测处理器
 * @author sprout
 * @version 1.0
 * 2022-07-02 22:40
 */
public class DefaultAutoDetectorHandler implements AutoDetectorHandler {

    /** 自动探测注册器 */
    private final DefaultAutoDetectorRegister autoDetectorRegister = new DefaultAutoDetectorRegister();

    /** Nut应用对象 */
    private final NutApplication nutApplication;

    /**
     * 构建默认的自动检测处理器
     * @param nutApplication Nut应用对象
     */
    public DefaultAutoDetectorHandler(NutApplication nutApplication) {
        this.nutApplication = nutApplication;

        autoDetectorRegister.registerAutoDetector(new JsonResponsivePluginAutoDetectorProvider(nutApplication.getNutConfigure()));
        autoDetectorRegister.registerAutoDetector(new XmlResponsivePluginAutoDetectorProvider(nutApplication.getNutConfigure()));
        autoDetectorRegister.registerAutoDetector(new ViewResolverAutoDetectorProvider(nutApplication.getNutWebConfigure().getWebViewConfigure()));
        autoDetectorRegister.registerAutoDetector(new HibernateMethodParamValidatorAutoDetectorProvider(nutApplication.getNutWebConfigure()));
    }

    /**
     * 获取自动探测注册器
     * @return 自动探测注册器
     */
    public AutoDetectorRegister getAutoDetectorRegister() {
        return autoDetectorRegister;
    }

    @Override
    public void handle() {
        Set<Class<? extends AutoDetector>> ignoreAutoDetectorClasses = (
                (NutConfigureImpl) nutApplication.getNutConfigure()).getIgnoreAutoDetectorClasses();
        ApplicationType applicationType = nutApplication.getApplicationType();
        for (AutoDetector autoDetector : autoDetectorRegister.getAutoDetectors()) {
            if (ignoreAutoDetectorClasses.stream().noneMatch(clazz -> clazz == autoDetector.getClass())
                    && autoDetector.isSupport(applicationType)) {
                autoDetector.autoDetect();
            }
        }
    }
}
